use chrono::{DateTime, Datelike, Duration, NaiveDateTime, TimeZone, Utc};
use rand::prelude::*;
use rand_distr::{Normal, Uniform};
use serde::{Deserialize, Serialize};
use std::collections::HashMap;

use crate::objects::{NewBar as Bar, Freq};

/// 生成单个品种指定频率的K线数据
pub fn generate_symbol_kines(
    symbol: &str,
    freq: Freq,
    sdt: &str,
    edt: &str,
    seed: u64,
) -> Vec<Bar> {
    let mut rng = StdRng::seed_from_u64(seed + symbol.len() as u64);
    
    // 解析日期
    let start_date = NaiveDateTime::parse_from_str(&format!("{} 00:00:00", sdt), "%Y%m%d %H:%M:%S")
        .unwrap();
    let end_date = NaiveDateTime::parse_from_str(&format!("{} 00:00:00", edt), "%Y%m%d %H:%M:%S")
        .unwrap();
    
    // 生成时间序列
    let dates = generate_time_series(&start_date, &end_date, &freq);
    
    // 定义市场阶段
    let phases = vec![
        MarketPhase {
            name: "熊市".to_string(),
            trend: -0.0008,
            volatility: 0.025,
            length: 0.3,
        },
        MarketPhase {
            name: "震荡".to_string(),
            trend: 0.0002,
            volatility: 0.015,
            length: 0.2,
        },
        MarketPhase {
            name: "牛市".to_string(),
            trend: 0.0012,
            volatility: 0.02,
            length: 0.3,
        },
        MarketPhase {
            name: "调整".to_string(),
            trend: -0.0005,
            volatility: 0.02,
            length: 0.2,
        },
    ];
    
    let mut bars = Vec::new();
    let mut base_price = 100.0;
    let total_periods = dates.len();
    let mut phase_idx = 0;
    let mut phase_periods = 0;
    let mut current_phase = &phases[phase_idx];
    
    for (i, dt) in dates.iter().enumerate() {
        // 切换市场阶段
        if phase_periods >= (total_periods as f64 * current_phase.length) as usize {
            phase_idx = (phase_idx + 1) % phases.len();
            current_phase = &phases[phase_idx];
            phase_periods = 0;
        }
        
        let trend = current_phase.trend;
        let volatility = current_phase.volatility;
        
        // 调整分钟级数据的趋势和波动率
        let adjusted_trend = if freq != Freq::Day {
            trend * 0.1
        } else {
            trend
        };
        
        let adjusted_volatility = if freq != Freq::Day {
            volatility * 0.5
        } else {
            volatility
        };
        
        // 生成价格变化
        let normal = Normal::new(adjusted_trend, adjusted_volatility).unwrap();
        let price_change = normal.sample(&mut rng);
        base_price *= (1.0 + price_change).max(0.1);
        
        // 生成OHLC
        let high_change = Uniform::new(0.0, 0.02).sample(&mut rng);
        let low_change = Uniform::new(-0.02, 0.0).sample(&mut rng);
        let open_change = Uniform::new(-0.01, 0.01).sample(&mut rng);
        
        let open = base_price * (1.0 + open_change);
        let close = base_price;
        let high = base_price * (1.0 + high_change);
        let low = base_price * (1.0 + low_change);
        
        // 生成成交量
        let volume = Uniform::new(1000.0, 100000.0).sample(&mut rng);
        let amount = volume * close;
        
        let bar = Bar::new(
            symbol.to_string(),
            bars.len() as i32,
            DateTime::from_naive_utc_and_offset(*dt, Utc),
            freq.clone(),
            open,
            close,
            high,
            low,
            volume,
            amount,
        );
        
        bars.push(bar);
        phase_periods += 1;
    }
    
    bars
}

/// 市场阶段结构
#[derive(Debug)]
struct MarketPhase {
    name: String,
    trend: f64,
    volatility: f64,
    length: f64,
}

/// 生成时间序列
fn generate_time_series(start: &NaiveDateTime, end: &NaiveDateTime, freq: &Freq) -> Vec<NaiveDateTime> {
    let mut dates = Vec::new();
    let mut current = *start;
    
    while current <= *end {
        match freq {
            Freq::Day => {
                dates.push(current);
                current += Duration::days(1);
            }
            Freq::Min1 | Freq::Min5 | Freq::Min15 | Freq::Min30 => {
                let minutes = match freq {
                    Freq::Min1 => 1,
                    Freq::Min5 => 5,
                    Freq::Min15 => 15,
                    Freq::Min30 => 30,
                    _ => 1,
                };
                
                // 生成交易时间
                let trading_times = generate_trading_times(&current, minutes);
                dates.extend(trading_times);
                
                current += Duration::days(1);
            }
            _ => {
                // 其他频率暂不支持
                break;
            }
        }
    }
    
    dates
}

/// 生成交易时间
fn generate_trading_times(date: &NaiveDateTime, minutes: i64) -> Vec<NaiveDateTime> {
    let mut times = Vec::new();
    
    // 上午交易时间 09:30-11:30
    let morning_start = date.date().and_hms_opt(9, 30, 0).unwrap();
    let morning_end = date.date().and_hms_opt(11, 30, 0).unwrap();
    
    let mut current = morning_start;
    while current <= morning_end {
        times.push(current);
        current += Duration::minutes(minutes);
    }
    
    // 下午交易时间 13:00-15:00
    let afternoon_start = date.date().and_hms_opt(13, 0, 0).unwrap();
    let afternoon_end = date.date().and_hms_opt(15, 0, 0).unwrap();
    
    let mut current = afternoon_start;
    while current <= afternoon_end {
        times.push(current);
        current += Duration::minutes(minutes);
    }
    
    times
}

/// 生成K线数据
pub fn generate_klines(seed: u64) -> Vec<Bar> {
    generate_symbol_kines("000001.SH", Freq::Day, "20200101", "20231231", seed)
}

/// 生成带权重的K线数据
pub fn generate_klines_with_weights(seed: u64) -> Vec<Bar> {
    generate_klines(seed)
}

/// 生成时间序列因子
pub fn generate_ts_factor(seed: u64) -> HashMap<String, Vec<f64>> {
    let mut rng = StdRng::seed_from_u64(seed);
    let mut result = HashMap::new();
    
    let n = 252; // 一年的交易日
    let mut factor1 = Vec::new();
    let mut factor2 = Vec::new();
    
    for _ in 0..n {
        factor1.push(normal_distribution(&mut rng, 0.0, 1.0));
        factor2.push(normal_distribution(&mut rng, 0.0, 1.0));
    }
    
    result.insert("factor1".to_string(), factor1);
    result.insert("factor2".to_string(), factor2);
    
    result
}

/// 生成横截面因子
pub fn generate_cs_factor(seed: u64) -> HashMap<String, Vec<f64>> {
    let mut rng = StdRng::seed_from_u64(seed);
    let mut result = HashMap::new();
    
    let n = 100; // 股票数量
    let mut factor1 = Vec::new();
    let mut factor2 = Vec::new();
    
    for _ in 0..n {
        factor1.push(normal_distribution(&mut rng, 0.0, 1.0));
        factor2.push(normal_distribution(&mut rng, 0.0, 1.0));
    }
    
    result.insert("factor1".to_string(), factor1);
    result.insert("factor2".to_string(), factor2);
    
    result
}

/// 生成策略收益
pub fn generate_strategy_returns(n_strategies: usize, n_days: Option<usize>, seed: u64) -> HashMap<String, Vec<f64>> {
    let mut rng = StdRng::seed_from_u64(seed);
    let mut result = HashMap::new();
    
    let days = n_days.unwrap_or(252);
    
    for i in 0..n_strategies {
        let mut returns = Vec::new();
        for _ in 0..days {
            returns.push(normal_distribution(&mut rng, 0.001, 0.02));
        }
        result.insert(format!("strategy_{}", i + 1), returns);
    }
    
    result
}

/// 生成投资组合数据
pub fn generate_portfolio(seed: u64) -> HashMap<String, Vec<f64>> {
    generate_strategy_returns(5, Some(252), seed)
}

/// 设置全局随机种子
pub fn set_global_seed(seed: u64) {
    // Rust中通过传递seed参数来控制随机性
    // 这里主要是为了保持API兼容性
}

/// 生成相关性数据
pub fn generate_correlation_data(seed: u64) -> HashMap<String, Vec<f64>> {
    let mut rng = StdRng::seed_from_u64(seed);
    let mut result = HashMap::new();
    
    let n = 100;
    let mut asset1 = Vec::new();
    let mut asset2 = Vec::new();
    let mut asset3 = Vec::new();
    
    for _ in 0..n {
        asset1.push(normal_distribution(&mut rng, 0.001, 0.02));
        asset2.push(normal_distribution(&mut rng, 0.001, 0.02));
        asset3.push(normal_distribution(&mut rng, 0.001, 0.02));
    }
    
    result.insert("asset1".to_string(), asset1);
    result.insert("asset2".to_string(), asset2);
    result.insert("asset3".to_string(), asset3);
    
    result
}

/// 生成日收益数据
pub fn generate_daily_returns(n_strategies: usize, seed: u64) -> HashMap<String, Vec<f64>> {
    generate_strategy_returns(n_strategies, Some(252), seed)
}

/// 生成统计数据
pub fn generate_statistics_data(seed: u64) -> HashMap<String, Vec<f64>> {
    let mut rng = StdRng::seed_from_u64(seed);
    let mut result = HashMap::new();
    
    let n = 1000;
    let mut data = Vec::new();
    
    for _ in 0..n {
        data.push(normal_distribution(&mut rng, 0.0, 1.0));
    }
    
    result.insert("data".to_string(), data);
    
    result
}

/// 生成事件数据
pub fn generate_event_data(seed: u64) -> Vec<Event> {
    let mut rng = StdRng::seed_from_u64(seed);
    let mut events = Vec::new();
    
    let event_types = vec!["买入", "卖出", "止损", "止盈"];
    let symbols = vec!["000001.SH", "000002.SZ", "000300.SH"];
    
    for i in 0..100 {
        let event_type = event_types[rng.gen_range(0..event_types.len())].to_string();
        let symbol = symbols[rng.gen_range(0..symbols.len())].to_string();
        let price = uniform_distribution(&mut rng, 10.0, 100.0);
        let volume = uniform_distribution(&mut rng, 100.0, 10000.0);
        
        let event = Event {
            id: i,
            dt: Utc::now() + Duration::days(i as i64),
            symbol,
            event_type,
            price,
            volume,
        };
        
        events.push(event);
    }
    
    events
}

/// 事件结构
#[derive(Debug, Serialize, Deserialize)]
pub struct Event {
    pub id: usize,
    pub dt: DateTime<Utc>,
    pub symbol: String,
    pub event_type: String,
    pub price: f64,
    pub volume: f64,
}

/// 正态分布随机数生成
fn normal_distribution(rng: &mut StdRng, mean: f64, std: f64) -> f64 {
    let normal = Normal::new(mean, std).unwrap();
    normal.sample(rng)
}

/// 均匀分布随机数生成
fn uniform_distribution(rng: &mut StdRng, min: f64, max: f64) -> f64 {
    let uniform = Uniform::new(min, max);
    uniform.sample(rng)
} 